package cn.changeforyou.web.dao.mybatis.ext.extBuilder.builder;

import cn.changeforyou.web.dao.mybatis.ext.extBuilder.DaoSpringHolder;
import cn.changeforyou.web.dao.mybatis.ext.extBuilder.SqlContext;
import cn.changeforyou.web.dao.mybatis.ext.extBuilder.writer.InsertEntityListSqlWriter;
import cn.changeforyou.web.dao.mybatis.ext.extBuilder.writer.InsertEntitySqlWriter;
import cn.changeforyou.web.dao.mybatis.ext.metaInfo.*;

import java.util.ArrayList;
import java.util.List;

/**
 * insert语句构建器
 * @author zhyu
 * @version 1.0
 * @date 2022/2/10 16:36
 */
public class InsertBuilder {

    private static InsertEntitySqlWriter insertEntitySqlWriter;
    private static InsertEntityListSqlWriter insertEntityListSqlWriter;

    static {
        insertEntitySqlWriter = DaoSpringHolder.getBean(InsertEntitySqlWriter.class);
        insertEntityListSqlWriter = DaoSpringHolder.getBean(InsertEntityListSqlWriter.class);
    }

    /**
     * 构建
     * @param mappedStatementMetaInfo
     * @return
     */
    public static void buildAndSet(MappedStatementMetaInfo mappedStatementMetaInfo){
        SqlContext sqlContext = prepareBuild(mappedStatementMetaInfo);

        //处理类型
        if(sqlContext.getMappedStatementParameterType() == MappedStatementParameterType.insertEntity || sqlContext.getMappedStatementParameterType() == MappedStatementParameterType.insertDto) {
            insertEntitySqlWriter.writeSql(sqlContext);
        }else if(sqlContext.getMappedStatementParameterType() == MappedStatementParameterType.insertList || sqlContext.getMappedStatementParameterType() == MappedStatementParameterType.insertDtoList) {
            insertEntityListSqlWriter.writeSql(sqlContext);
        }

        mappedStatementMetaInfo.setSql(sqlContext.getSql().toString());
    }

    private static SqlContext prepareBuild(MappedStatementMetaInfo mappedStatementMetaInfo) {
        SqlContext sqlContext = new SqlContext();
        sqlContext.setSqlCommandType(mappedStatementMetaInfo.getSqlCommandType());
        sqlContext.setMappedStatementResultType(mappedStatementMetaInfo.getMappedStatementBaseInfo().getMappedStatementResultType());
        MappedStatementParameterType mappedStatementParameterType = mappedStatementMetaInfo.getMappedStatementBaseInfo().getMappedStatementParameterType();
        sqlContext.setMappedStatementParameterType(mappedStatementParameterType);
        List<FieldMetaInfo> fieldMetaInfoList = null;
        if (mappedStatementParameterType == MappedStatementParameterType.insertDto || mappedStatementParameterType == MappedStatementParameterType.insertDtoList) {
            fieldMetaInfoList = mappedStatementMetaInfo.getDtoMetaInfo().getFieldMetaInfoList();
        } else {
            fieldMetaInfoList = mappedStatementMetaInfo.getEntityMetaInfo().getFieldMetaInfoList();
        }

        List<FieldMetaInfo> insertFieldMetaInfoList = new ArrayList<>(fieldMetaInfoList.size());
        for (FieldMetaInfo fieldMetaInfo : fieldMetaInfoList) {
            if (fieldMetaInfo.isId()) {
                sqlContext.setPrimaryKeyInfo(fieldMetaInfo);
                if (fieldMetaInfo.getIdTypeEnum() != IdTypeEnum.auto) {
                    insertFieldMetaInfoList.add(fieldMetaInfo);
                }
            } else {
                insertFieldMetaInfoList.add(fieldMetaInfo);
            }
        }
        EntityMetaInfo insertMetaInfo = new EntityMetaInfo();
        insertMetaInfo.setTableName(mappedStatementMetaInfo.getEntityMetaInfo().getTableName());
        insertMetaInfo.setFieldMetaInfoList(insertFieldMetaInfoList);

        sqlContext.setInsertMetaInfo(insertMetaInfo);
        return sqlContext;
    }
}
